import { Card, Breadcrumb, Form, Radio, Input, Upload, Select, message, UploadFile, RadioChangeEvent, FormInstance } from 'antd'
import { PlusOutlined } from '@ant-design/icons'
import { Link, useNavigate, useSearchParams } from 'react-router-dom'
import './Publish.scss'
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
import { useEffect, useRef, useState } from 'react';
import { ArticleType, publishArticleAPI, selectArticleDataAPI, updateArticleAPI } from '@/apis/articleApi';
import FormSubmitButton from '@/components/FormSubmitButton/FormSubmitButton';
import useChannel from '@/hooks/useChannel';
import { UploadChangeParam } from 'antd/es/upload';

const { Option } = Select;

type CoverUploaderPropsType = {
    coverType: number,
    coverList: Array<UploadFile>,
    setCoverType: (coverType: number) => void,
    setCoverList: (coverList: Array<UploadFile>) => void,
};

// 封面上传
const CoversUploader = (props: CoverUploaderPropsType) => {
    // 解构props
    const { coverType, setCoverType, coverList, setCoverList } = props;
    // 封面缓存
    const fileCache = useRef<Array<UploadFile>>([]);

    // 封面类型切换事件
    const onCoverTypeChange = (e: RadioChangeEvent) => {
        setCoverType(e.target.value);
        // 应用缓存
        if (e.target.value) {
            setCoverList(fileCache.current.slice(0, e.target.value));
        }
    };

    // 封面图集切换事件
    const onFileListChange = ({ file, fileList }: UploadChangeParam) => {
        if (file.status === 'error') message.error(file.response.message);
        // 筛选上传状态不为error的文件
        const validCoverList = fileList.filter(item => item.status !== 'error');
        setCoverList(validCoverList);
        // 缓存图集
        fileCache.current = validCoverList;
    };

    return (
        <Form.Item label="封面">
            <Form.Item name="type">
                <Radio.Group onChange={onCoverTypeChange}>
                    <Radio value={1}>单图</Radio>
                    <Radio value={3}>三图</Radio>
                    <Radio value={0}>无图</Radio>
                </Radio.Group>
            </Form.Item>
            {coverType ? <Upload
                fileList={coverList}
                accept='image/*'
                listType="picture-card"
                showUploadList
                name='image'
                action={'http://geek.itheima.net/v1_0/upload'}
                multiple={coverType > 1}
                maxCount={coverType}
                onChange={onFileListChange}>
                <div style={{ marginTop: 8 }}>
                    <PlusOutlined />
                </div>
            </Upload> : <></>}
        </Form.Item>
    );
};

// 发布文章组件
const Publish = () => {
    // 表单实例
    const formRef = useRef<FormInstance>(null);
    // 频道hook
    const { channels } = useChannel();
    // 封面类型
    const [coverType, setCoverType] = useState(1);
    // 封面图集
    const [coverList, setCoverList] = useState<Array<UploadFile>>([]);
    // 加载标志
    const [loading, setLoading] = useState<boolean>(false);
    // 路由
    const navigate = useNavigate();
    // 路由参数
    const [routerParams] = useSearchParams();
    // 获取文章ID
    const articleId = routerParams.get('id');

    // 数据回显
    useEffect(() => {
        if (articleId) selectArticleDataAPI(articleId).request.then(response => {
            const { cover, ...formData } = response.data;
            // 填充基础数据
            formRef.current?.setFieldsValue(formData);
            // 填充封面信息
            setCoverList(cover.images.map(url => ({ url } as UploadFile)));
        });
    }, [articleId]);

    // 提交方法
    const publish = ({ channel_id, content, title }: ArticleType) => {
        if (coverList.length !== coverType) return message.warning('封面实际数量与选择不符！');
        // 封装文章数据
        const article = {
            channel_id,
            content,
            title,
            cover: {
                type: coverType,
                images: coverList.map(item => item.response?.data.url || item.url),
            }
        };
        // 重置表单
        const resetFormData = () => {
            formRef.current?.resetFields();
            setCoverType(1);
            setCoverList([]);
        };
        setLoading(true);
        if (articleId) {
            // 修改文章
            updateArticleAPI(articleId, article).request.then(() => {
                setLoading(false);
                resetFormData();
                message.success('修改成功！');
                navigate('/article');
            })
        } else {
            // 发布文章
            publishArticleAPI(article).request.then(() => {
                setLoading(false);
                resetFormData();
                message.success('发布成功！');
            }).catch(() => {
                setLoading(false);
            });
        }
    };

    return (
        <div className="publish">
            <Card
                title={
                    <Breadcrumb items={[
                        { title: <Link to={'/'}>首页</Link> },
                        { title: articleId ? '编辑文章' : '发布文章' },
                    ]} />
                }>
                <Form ref={formRef}
                    labelCol={{ span: 4 }}
                    wrapperCol={{ span: 16 }}
                    initialValues={{ type: 1 }}
                    onFinish={publish}>
                    <Form.Item
                        label="标题"
                        name="title"
                        rules={[{ required: true, message: '请输入文章标题' }]}
                        validateTrigger='onBlur'>
                        <Input placeholder="请输入文章标题" style={{ width: 400 }} />
                    </Form.Item>
                    <Form.Item
                        label="频道"
                        name="channel_id"
                        rules={[{ required: true, message: '请选择文章频道' }]}
                        validateTrigger='onBlur'>
                        <Select placeholder="请选择文章频道" style={{ width: 400 }}>
                            {channels.map(item => (
                                <Option key={item.id} value={item.id}>{item.name}</Option>
                            ))}
                        </Select>
                    </Form.Item>
                    <Form.Item
                        label="内容"
                        name="content"
                        rules={[{ required: true, message: '请输入文章内容' }]}
                        validateTrigger='onBlur'>
                        <ReactQuill className='publish-quill' theme='snow' />
                    </Form.Item>
                    <CoversUploader
                        coverType={coverType}
                        setCoverType={coverType => setCoverType(coverType)}
                        coverList={coverList}
                        setCoverList={coverList => setCoverList(coverList)} />
                    <Form.Item wrapperCol={{ offset: 4 }}>
                        <FormSubmitButton loading={loading} text={articleId ? '编辑文章' : '发布文章'} />
                    </Form.Item>
                </Form>
            </Card>
        </div>
    )
}

export default Publish